needs Approval
Approval gate. Per historical parity gap #17, the predicate receives ToolPredicateOptions (toolCallId + messages + experimental_context) — not just context. Lets the gate decide based on conversation history or call identity.